(require 'srfi-1)

(define (single? ls)
  (and (pair? ls) (null? (cdr ls))))

; you can allways just cons more stuff on the font of an alist
; the new stuff will shadow the old stuff. this takes an alist 
; and a replacement, it builds a new alist. very inneficent implementation
(define (alist-replace key val ls)
  (cond
    ((null? ls) (alist-cons key val ls))
    ((eq? key (car (car ls))) (alist-cons key val (cdr ls)))
    (else (cons (car ls) (alist-replace key val (cdr ls))))))
; given (atree '(a b c) '((a ((b ((c 1))))))) should return (c 1)
; so for an arbitrary tree, pass in a path to get that section 
; of the tree
(define (atree path tree)
  (cond
    ((null? tree) #f)
    ((null? path) #f)
    ((single? path) (assoc (first path) tree))
    (else
      (let ((res (assoc (first path) tree)))
        (if res
          (atree (cdr path) (second res))
          #f)))))

;the tree version of alist-replace
(define (atree-insert path value tree)
  (if (null? path)
    tree
    (let ((res (assoc (car path) tree)))
      (if (single? path) 
        (alist-cons (first path) value tree)
        (alist-replace (car path) 
                       (list
                         (atree-insert (cdr path) 
                                            value 
                                            (if res (second res) '())))
                       tree)))))


;(define sample-tree (atree-insert '(a b c) 1 
;(atree-insert '(a b d) 2
;(atree-insert '(a c d) 3 '()))))







